/*
 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle or the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package ihm.loader;

import ihm.applet.KrakenApplet;
import ihm.tool.AppletConstant;

import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.net.URL;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

import tools.ConfParser;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;

import com.sun.jna.NativeLibrary;

public class JProgressBarExtended extends JPanel implements PropertyChangeListener {

	private static final long serialVersionUID = 1L;
	private JProgressBar progressBar;
	private Task task;
	
	private String classArray[] = {
			"bdd.standalone.bean.Alert",
			"bdd.standalone.bean.AppletLog",
			"bdd.standalone.bean.Camera",
			"bdd.standalone.bean.CameraOptions",
			"bdd.standalone.bean.CameraPlanning",
			"bdd.standalone.bean.DatabasePlanning",
			"bdd.standalone.bean.Encryption",
			"bdd.standalone.bean.GlobalServer",
			"bdd.standalone.bean.Log",
			"bdd.standalone.bean.Planning",
			"bdd.standalone.bean.QoS",
			"bdd.standalone.bean.QoSPlanning",
			"bdd.standalone.bean.Right",
			"bdd.standalone.bean.SiteServer",
			"bdd.standalone.bean.StorageServer",
			"bdd.standalone.bean.Treatment",
			"bdd.standalone.bean.User",
			"bdd.standalone.bean.User_Log",
			"bdd.standalone.bean.Video",
			"bdd.standalone.bean.WebServer",
			
			"bdd.standalone.hibernate.HibernateUtil",
			
			"bdd.standalone.configuration.DatabaseConfiguration",
			
			"enumTypes.Civility",
			"enumTypes.LogType",
			"enumTypes.Rank",
			
			// loader, and applet classes not included, already loaded
			
			"ihm.panel.admin.AdministrationPanel",
			"ihm.panel.admin.ListUsersPanel",
			"ihm.panel.admin.NewUserPanel",
			"ihm.panel.admin.UserRightsPanel",
			
			"ihm.panel.camera.CameraOptionsPanel",
			"ihm.panel.camera.CameraPanel",
			"ihm.panel.camera.StockagePanel",
			"ihm.panel.camera.VideoPanel",
			
			"ihm.panel.edit.ParamPanel",
			
			"ihm.panel.file.ChangePassword",
			"ihm.panel.file.LoginPanel",
			"ihm.panel.file.WelcomePanel",
			
			"ihm.panel.info.AlertPanel",
			"ihm.panel.info.LoggerPanel",
			
			"ihm.panel.node.NodePanel",
			
			//"ihm.panel.qos.QoSConfPanel",
			
			"ihm.panel.site.CipherPanel",
			//"ihm.panel.site.QoSPanel",
			
			"ihm.panel.video.FluxPanel",
			"ihm.panel.video.PlayerControlsPanel",
			"ihm.panel.video.PlayerVideoAdjustPanel",
			
			"ihm.panel.KrakenTablePanel",
			"ihm.panel.PanelInterface",
			"ihm.panel.TablePanel",
			
			"ihm.table.AppletTable",
			"ihm.table.AppletTableModel",
			
			"ihm.tool.AppletConstant",
			"ihm.tool.EMailVerificator",
			"ihm.tool.Logger",

			"network.KrakenClient",
			"network.KrakenClientMsg",
			//"network.KrakenCommandInterpreter",
			//"network.KrakenCommandMaker",
			//"network.KrakenServer",
			//"network.KrakenServerMsg",
			//"network.KrakenThread",
			//"network.TestServer",

			"security.configuration.SecurityConfiguration",
			"security.encryption.FlowEncryption",

			"tools.FileUtils",
			"tools.PasswordSecurity",

			// ommiting vlcj tests, unused, video packages

		};

	class Task extends SwingWorker<Void, Void> {
		/*
		 * Main task. Executed in background thread.
		 */
		@Override
		public Void doInBackground() {
			int progress = 0;
			setProgress(0);
			
			// preload classes
			for(int i = 0; i < classArray.length; ++ i) {
				Class c;
				try {
					// load vlc
					if(classArray[i].equals("ihm.panel.video.FluxPanel")) {
						ConfParser parser = new ConfParser();
						parser.parse(new File(System.getProperty("user.home")+"\\kraken\\kraken.cfg"));
						// va chercher les bibliothèques dans l'ordre
						NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:\\Program Files\\VideoLAN\\VLC");
						NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:\\Program Files (x86)\\VideoLAN\\VLC");
						NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), parser.getValue("VLCpath"));
						// TODO aller chercher les chemins par défaut dans le fichier de configuration vlc sur le serveur web
						MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
					}
					c = Class.forName(classArray[i]);
					progress++;
					setProgress(progress);
				} catch (ClassNotFoundException | IOException e) {
					e.printStackTrace();
				}
			}
			return null;
		}

		/*
		 * Executed in event dispatch thread
		 */
		public void done() {
			Toolkit.getDefaultToolkit().beep();
		}
	}

	public JProgressBarExtended() {
		super(new BorderLayout());
		
		progressBar = new JProgressBar(0, 58);
		progressBar.setValue(0);
		progressBar.setPreferredSize(AppletConstant.FIELD_SIZE);

		//Call setStringPainted now so that the progress bar height
		//stays the same whether or not the string is shown.
		progressBar.setStringPainted(true); 

		JPanel panel = new JPanel();
		panel.add(progressBar);

		add(panel, BorderLayout.PAGE_START);
		setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
	}

	public void load() {
		progressBar.setIndeterminate(true);
		task = new Task();
		task.addPropertyChangeListener(this);
		task.execute();
	}

	/**
	 * Invoked when task's progress property changes.
	 */
	public void propertyChange(PropertyChangeEvent evt) {
		if ("progress" == evt.getPropertyName()) {
			int progress = (Integer) evt.getNewValue();
			progressBar.setIndeterminate(false);
			progressBar.setValue(progress);
		}
	}

	/**
	 * Create the GUI and show it. As with all GUI code, this must run
	 * on the event-dispatching thread.
	 */
	private static void createAndShowGUI() {
		//Create and set up the window.
		JFrame frame = new JFrame("ProgressBarDemo2");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		//Create and set up the content pane.
		JComponent newContentPane = new JProgressBarExtended();
		newContentPane.setOpaque(true); //content panes must be opaque
		frame.setContentPane(newContentPane);

		//Display the window.
		frame.pack();
		frame.setVisible(true);
		((JProgressBarExtended)newContentPane).load();
	}

	public static void main(String[] args) {
		//Schedule a job for the event-dispatching thread:
		//creating and showing this application's GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}
}
